//
//  CJExten+UIColor.swift
//  CJCore
//
//  Created by 陈警卫 on 2024-06-18.
//

import UIKit
import Foundation

public extension UIColor {
    
    /// RGBA颜色
    @objc static func cj_color(r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat = 1.0) -> UIColor {
        return UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a)
    }
    
    /// 随机颜色
    @objc static var cj_colorRandom: UIColor {
        return cj_color(r: CGFloat(arc4random_uniform(256)),
                        g: CGFloat(arc4random_uniform(256)),
                        b: CGFloat(arc4random_uniform(256)))
    }
    
    /// hexStrColor
    @objc static func cj_color(hexStr: String, alpha: CGFloat = 1.0) -> UIColor {
        let hexColor = hexStr.replacingOccurrences(of: "#", with: "")
        var tred:   CGFloat = 0.0
        var tgreen: CGFloat = 0.0
        var tblue:  CGFloat = 0.0
        var talpha: CGFloat = 1.0
        let scanner = Scanner(string: hexColor)
        var colorValue: CUnsignedLongLong = 0
        if scanner.scanHexInt64(&colorValue) {
            switch hexColor.count {
            case 3: // #RGB
                tred   = CGFloat((colorValue & 0xF00) >> 8)       / 15.0
                tgreen = CGFloat((colorValue & 0x0F0) >> 4)       / 15.0
                tblue  = CGFloat((colorValue & 0x00F))            / 15.0
                talpha = alpha
            case 4: // #RGBA
                tred   = CGFloat((colorValue & 0xF000) >> 12)     / 15.0
                tgreen = CGFloat((colorValue & 0x0F00) >> 8)      / 15.0
                tblue  = CGFloat((colorValue & 0x00F0) >> 4)      / 15.0
                talpha = CGFloat((colorValue & 0x000F))           / 15.0
            case 6: // #RRGGBB
                tred   = CGFloat((colorValue & 0xFF0000) >> 16)   / 255.0
                tgreen = CGFloat((colorValue & 0x00FF00) >> 8)    / 255.0
                tblue  = CGFloat((colorValue & 0x0000FF))         / 255.0
                talpha = alpha
            case 8: // #RRGGBBAA
                tred   = CGFloat((colorValue & 0xFF000000) >> 24) / 255.0
                tgreen = CGFloat((colorValue & 0x00FF0000) >> 16) / 255.0
                tblue  = CGFloat((colorValue & 0x0000FF00) >> 8)  / 255.0
                talpha = CGFloat((colorValue & 0x000000FF))       / 255.0
            default:
                print("#CJExten+UIColor# Invalid RGB string, number of characters after '#' should be either 3, 4, 6 or 8");
            }
        }
        return UIColor(red: tred, green: tgreen, blue: tblue, alpha: talpha)
    }
    
    /// hexColor
    @objc static func cj_color(hex: UInt, alpha: CGFloat = 1.0) -> UIColor {
        return UIColor(red:   CGFloat((hex & 0xFF0000) >> 16)/255.0,
                       green: CGFloat((hex & 0xFF00) >> 8)/255.0,
                       blue:  CGFloat((hex & 0xFF))/255.0,
                       alpha: alpha)
    }
    
    /// hexStrColor
    static func cj_color(_ hex: String, alpha: CGFloat = 1.0) -> UIColor {
        return cj_color(hexStr: hex, alpha: alpha)
    }
    
    /// hexColor
    static func cj_color(_ hex: UInt, alpha: CGFloat = 1.0) -> UIColor {
        return cj_color(hex: hex, alpha: alpha)
    }
    
    /// 颜色渐变
    @objc static func cj_colorGradual(fColor: UIColor, tColor: UIColor, progress: CGFloat) -> UIColor {
        
        var tprogress = progress
        tprogress = tprogress < 0.0 ? 0.0 : tprogress
        tprogress = tprogress > 1.0 ? 1.0 : tprogress
        
        let fRed = fColor.cj_red
        let fGreen = fColor.cj_green
        let fBlue = fColor.cj_blue
        let fAlpha = fColor.cj_alpha
        
        let tRed = tColor.cj_red
        let tGreen = tColor.cj_green
        let tBlue = tColor.cj_blue
        let tAlpha = tColor.cj_alpha
        
        let finalRed = fRed + (tRed - fRed) * tprogress
        let finalGreen = fGreen + (tGreen - fGreen) * tprogress
        let finalBlue = fBlue + (tBlue - fBlue) * tprogress
        let finalAlpha = fAlpha + (tAlpha - fAlpha) * tprogress
        
        return UIColor(red: finalRed, green: finalGreen, blue: finalBlue, alpha: finalAlpha)
    }
    
    /// 颜色融合 fromColor 背景色 toColor 前景色
    @objc static func cj_colorFuse(fromColor: UIColor, toColor: UIColor) -> UIColor {
        
        let fromRed = fromColor.cj_red
        let fromGreen = fromColor.cj_green
        let fromBlue = fromColor.cj_blue
        let fromAlpha = fromColor.cj_alpha
        
        let toRed = toColor.cj_red
        let toGreen = toColor.cj_green
        let toBlue = toColor.cj_blue
        let toAlpha = toColor.cj_alpha
        
        let finalAlpha = fromAlpha + toAlpha * (1 - fromAlpha)
        let finalRed = (fromRed * fromAlpha + toRed * toAlpha * (1 - fromAlpha)) / finalAlpha
        let finalGreen = (fromGreen * fromAlpha + toGreen * toAlpha * (1 - fromAlpha)) / finalAlpha
        let finalBlue = (fromBlue * fromAlpha + toBlue * toAlpha * (1 - fromAlpha)) / finalAlpha
        
        return UIColor(red: finalRed, green: finalGreen, blue: finalBlue, alpha: finalAlpha)
    }
    
    /// 适配Dark
    @objc static func cj_colorDynamic(lightColor: UIColor, darkColor: UIColor) -> UIColor {
        if #available(iOS 13.0, *) {
            let defaultColor = UIColor { trait in
                if trait.userInterfaceStyle == .light {
                    return lightColor
                } else {
                    return darkColor
                }
            }
            return defaultColor
        } else {
            return lightColor
        }
    }
    
    /// 适配Dark
    @objc static func cj_colorDynamic(lightHexStr: String, darkHexStr: String) -> UIColor {
        let lightColor = cj_color(hexStr: lightHexStr)
        let darkColor = cj_color(hexStr: darkHexStr)
        return cj_colorDynamic(lightColor: lightColor, darkColor: darkColor)
    }
    
    /// 适配Dark
    @objc static func cj_colorDynamic(lightHex: UInt, darkHex: UInt) -> UIColor {
        let lightColor = cj_color(hex: lightHex)
        let darkColor = cj_color(hex: darkHex)
        return cj_colorDynamic(lightColor: lightColor, darkColor: darkColor)
    }
}

public extension UIColor {
    
    /// 获取hexStr
    @objc func cj_hexString(alpha: Bool = false) -> String {
        
        guard let comps = self.cgColor.components else { return "" }
        let r = Int(comps[0] * 255)
        let g = Int(comps[1] * 255)
        let b = Int(comps[2] * 255)
        let a = Int(comps[3] * 255)
        
        var hexString = String(format: "%02X%02X%02X", r, g, b)
        if alpha {
            hexString += String(format: "%02X", a)
        }
        return hexString
    }
    
}

public extension UIColor {
    
    var cj_rgba: (CGFloat, CGFloat, CGFloat, CGFloat) {
        var (r, g, b, a): (CGFloat, CGFloat, CGFloat, CGFloat) = (0.0, 0.0, 0.0, 0.0)
        getRed(&r, green: &g, blue: &b, alpha: &a)
        return (r, g, b, a)
    }
    
    @objc var cj_red: CGFloat {
        var red: CGFloat = 0.0
        getRed(&red, green: nil, blue: nil, alpha: nil)
        return red
    }
    
    @objc var cj_green: CGFloat {
        var green: CGFloat = 0
        getRed(nil, green: &green , blue: nil, alpha: nil)
        return green
    }
    
    @objc var cj_blue: CGFloat {
        var blue: CGFloat = 0
        getRed(nil, green: nil , blue: &blue, alpha: nil)
        return blue
    }
    
    @objc var cj_alpha: CGFloat {
        var alpha: CGFloat = 0
        getRed(nil, green: nil , blue: nil, alpha: &alpha)
        return alpha
    }
    
    @objc var cj_hue: CGFloat {
        var hue: CGFloat = 0
        getHue(&hue, saturation: nil, brightness: nil, alpha: nil)
        return hue
    }
    
    @objc var cj_saturation: CGFloat {
        var saturation: CGFloat = 0
        getHue(nil, saturation: &saturation, brightness: nil, alpha: nil)
        return saturation
    }
    
    @objc var cj_brightness: CGFloat {
        var brightness: CGFloat = 0
        getHue(nil, saturation: nil, brightness: &brightness, alpha: nil)
        return brightness
    }
    
}
